package org.hepeng.workx.jdbc;

import org.apache.commons.collections.CollectionUtils;

import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author he peng
 */
public abstract class AbstractSelectDataSourceStrategy implements SelectDataSourceStrategy {

    private Map<String , DataSourceInfo> selectableDataSources = new ConcurrentHashMap<>();

    @Override
    public List<DataSourceInfo> getAllDataSources() {
        return new ArrayList<>(Collections.unmodifiableCollection(selectableDataSources.values()));
    }

    @Override
    public List<DataSource> getReadOnlyDataSources() {
        List<DataSource> readModeDataSources = new ArrayList<>();
        for (DataSourceInfo dataSourceInfo : selectableDataSources.values()) {
            if (Objects.equals(DataSourceInfo.DataSourceOpsMode.READ_ONLY , dataSourceInfo.getMode())) {
                readModeDataSources.add(dataSourceInfo.getDataSource());
            }
        }
        return Collections.unmodifiableList(readModeDataSources);
    }

    @Override
    public List<DataSource> getWriteOnlyDataSources() {
        List<DataSource> writeModeDataSources = new ArrayList<>();
        for (DataSourceInfo dataSourceInfo : selectableDataSources.values()) {
            if (Objects.equals(DataSourceInfo.DataSourceOpsMode.WRITE_ONLY , dataSourceInfo.getMode())) {
                writeModeDataSources.add(dataSourceInfo.getDataSource());
            }
        }
        return Collections.unmodifiableList(writeModeDataSources);
    }

    @Override
    public List<DataSource> getReadAndWriteDataSources() {
        List<DataSource> readAndWriteModeDataSources = new ArrayList<>();
        for (DataSourceInfo dataSourceInfo : selectableDataSources.values()) {
            if (Objects.equals(DataSourceInfo.DataSourceOpsMode.READ_AND_WRITE , dataSourceInfo.getMode())) {
                readAndWriteModeDataSources.add(dataSourceInfo.getDataSource());
            }
        }
        return Collections.unmodifiableList(readAndWriteModeDataSources);
    }

    @Override
    public void registerDataSource(DataSourceInfo dataSourceInfo) {
        if (Objects.nonNull(dataSourceInfo)) {
            selectableDataSources.put(dataSourceInfo.getId() , dataSourceInfo);
        }
    }

    @Override
    public void registerDataSource(List<DataSourceInfo> dataSourceInfos) {
        if (CollectionUtils.isNotEmpty(dataSourceInfos)) {
            dataSourceInfos.forEach(dataSourceInfo -> {
                if (Objects.nonNull(dataSourceInfo)) {
                    selectableDataSources.put(dataSourceInfo.getId() , dataSourceInfo);
                }
            });
        }
    }
}
